import json
import webapp2
from datetime import *
from google.appengine.ext import ndb
import logging
from Model import *
from NotificationsUtils import *

__author__ = 'Oryan'

distanceDict = {0:(0,10), 1:(0,0.5), 2:(0.5,1), 3:(1,5), 4:(5,10)}
nextWeek = datetime.today()+ timedelta(days=7)
nextMonth = datetime.today()+ timedelta(days=30)
dateDict = {0:datetime.max, 1:datetime.today(), 2:nextWeek, 3:nextMonth}

class MyRacesHandler(webapp2.RequestHandler):
    def get(self):
        user = ndb.Key('User', int(self.request.get("user")))
        races = Race.query(ndb.AND(Race.Participants.IN([user]),Race.Status == RaceStatus.Before))
        racesToJson = [{"Key": race.key.id(), "Manager": race.Manager.get().Name,\
                        "Distance": race.Distance, "Time": str(race.StartTime),\
                        "Tags" : race.Tags, "Participants":race.NumOfParticipants,\
                        "ManagerId": race.Manager.id(), "Estimated":race.EstimatedTime} for race in races]

        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(racesToJson))

class AllFutureRacesHandler(webapp2.RequestHandler):
    def get(self):
        user = ndb.Key('User', int(self.request.get("user")))
        races = Race.query(ndb.AND(Race.Status == RaceStatus.Before, Race.Privacy==RacePrivacy.Public))
        racesToJson = [{"Key": race.key.id(), "Manager": race.Manager.get().Name,\
                        "Distance": race.Distance, "Time": str(race.StartTime),\
                        "Tags" : race.Tags, "Participants":race.NumOfParticipants,\
                        "ManagerId": race.Manager.id(), "Estimated":race.EstimatedTime, "MyRace":(user in race.Participants)} for race in races]
        logging.info(racesToJson)
        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(racesToJson))

class FilterDistanceFutureRacesHandler(webapp2.RequestHandler):
    def get(self):
        user = ndb.Key('User', int(self.request.get("user")))
        requiredDistance = int(self.request.get("distance"))
        races = Race.query(ndb.AND(Race.Status == RaceStatus.Before, Race.Privacy==RacePrivacy.Public,\
                                   Race.Distance >= distanceDict[requiredDistance][0],  Race.Distance <= distanceDict[requiredDistance][1]))
        racesToJson = [{"Key": race.key.id(), "Manager": race.Manager.get().Name,\
                        "Distance": race.Distance, "Time": str(race.StartTime),\
                        "Tags" : race.Tags, "Participants":race.NumOfParticipants,\
                        "ManagerId": race.Manager.id(), "Estimated":race.EstimatedTime, "MyRace":(user in race.Participants)} for race in races]
        logging.info(racesToJson)
        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(racesToJson))

class FilterDateFutureRacesHandler(webapp2.RequestHandler):
    def get(self):
        user = ndb.Key('User', int(self.request.get("user")))
        requiredDate = int(self.request.get("date"))
        races = Race.query(ndb.AND(Race.Status == RaceStatus.Before, Race.Privacy==RacePrivacy.Public,\
                                   Race.StartTime <= dateDict[requiredDate]))
        racesToJson = [{"Key": race.key.id(), "Manager": race.Manager.get().Name,\
                        "Distance": race.Distance, "Time": str(race.StartTime),\
                        "Tags" : race.Tags, "Participants":race.NumOfParticipants,\
                        "ManagerId": race.Manager.id(), "Estimated":race.EstimatedTime, "MyRace":(user in race.Participants)} for race in races]
        logging.info(racesToJson)
        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(racesToJson))

class ParticipantsOfRaceHandler(webapp2.RequestHandler):
    def get(self):
        race = Race.get_by_id(int(self.request.get("race")))
        participantsToJson = []
        for participant in race.Participants:
            user = User.get_by_id(participant.id())
            ready = (participant in race.ReadyParticipants)
            participantsToJson.append({"Key":user.key.id(), "Name":user.Name, "Grade":user.Grade, "Ready":ready, "estimated":race.EstimatedTime})
        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(participantsToJson))

class NewRaceHandler(webapp2.RequestHandler):
    def get(self):
        distance = float(self.request.get("distance"))
        estimated = float(self.request.get("estimated"))
        manager = self.request.get("manager")
        tags = "#"+self.request.get("tags")
        year = int(self.request.get("year"))
        month = int(self.request.get("month"))
        day = int(self.request.get("day"))
        hour = self.request.get("hour")
        startTime = datetime(year, month, day, int(hour.split(':')[0]), int(hour.split(':')[1]))
        managerKey = ndb.Key('User', int(manager))
        if (self.request.get("privacy") == "Private"):
            privacy = RacePrivacy.Private
        else:
            privacy = RacePrivacy.Public

        race = Race(StartTime = startTime,
                    Distance = distance,
                    Privacy = privacy,
                    Generation = RaceGenerate.Manual,
                    EstimatedTime = estimated,
                    Tags = tags,
                    Manager = managerKey,
                     Status = RaceStatus.Before)
        race.Participants.append(managerKey)
        race.put()

        racesToJson = [{"raceID": race.key.id(), "Manager": race.Manager.get().Name,\
                        "Distance": race.Distance, "Time": str(race.StartTime),\
                        "Tags" : race.Tags, "Participants":race.NumOfParticipants,\
                        "ManagerId": race.Manager.id(), "Estimated":race.EstimatedTime}]
        self.response.out.write(json.dumps(racesToJson))

class AddUserToRace(webapp2.RequestHandler):
    def post(self):
        user = User.get_by_id(int(self.request.POST.get("user")))
        race = Race.get_by_id(int(self.request.POST.get("race")))
        if(not user.key in race.Participants):
            race.Participants.append(user.key)
        race.put()

        participantsToJson = []
        for participant in race.Participants:
            user = User.get_by_id(participant.id())
            ready = (participant in race.ReadyParticipants)
            participantsToJson.append({"Key":user.key.id(), "Name":user.Name, "Grade":user.Grade, "Ready":ready})
        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(participantsToJson))
        data = {'messageType':'RACER_READY'}
        res = sendMessageToClients(messageType = 'RACER_READY',registration_ids = [x.get().RegID for x in race.Participants] ,data=data )


class RemoveUserFromRace(webapp2.RequestHandler):
    def post(self):
        user = User.get_by_id(int(self.request.POST.get("user")))
        race = Race.get_by_id(int(self.request.POST.get("race")))
        data = {'messageType':'RACER_READY'}
        res = sendMessageToClients(messageType = 'RACER_READY',registration_ids = [x.get().RegID for x in race.Participants] ,data=data )
        if user.key in race.Participants:
            race.Participants.remove(user.key)
        if user.key in race.ReadyParticipants:
            race.ReadyParticipants.remove(user.key)
        race.put()
        participantsToJson = []
        for participant in race.Participants:
            user = User.get_by_id(participant.id())
            ready = (participant in race.ReadyParticipants)
            participantsToJson.append({"Key":user.key.id(), "Name":user.Name, "Grade":user.Grade, "Ready":ready})
        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(participantsToJson))



class AddUserToReady(webapp2.RequestHandler):
    def post(self):
        user = User.get_by_id(int(self.request.POST.get("user")))
        race = Race.get_by_id(int(self.request.POST.get("race")))
        if user.key in race.Participants and user.key not in race.ReadyParticipants:
            race.ReadyParticipants.append(user.key)
        race.put()

        participantsToJson = []
        for participant in race.Participants:
            user = User.get_by_id(participant.id())
            ready = (participant in race.ReadyParticipants)
            participantsToJson.append({"Key":user.key.id(), "Name":user.Name, "Grade":user.Grade, "Ready":ready})
        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps(participantsToJson))

        data = {'messageType':'RACER_READY'}
        res = sendMessageToClients(messageType = 'RACER_READY',registration_ids = [x.get().RegID for x in race.Participants] ,data=data )

class NewCurrentStatsHandler(webapp2.RequestHandler):
    def get(self):
        raceID = int(self.request.get("raceID"))
        racerID = int(self.request.get("racerID"))
        speed = float(self.request.get("speed"))
        actualDistance = float(self.request.get("actualDistance"))
        stat = CurrentStats(Race = ndb.Key('Race', raceID),
                            Racer = ndb.Key('User', racerID),
                            Name = ndb.Key('User', racerID).get().Name,
                            Speed = speed,
                            ActualDistance = actualDistance,
                            Status = RacerStatus.NotReady,
                            FinishedPosition = -1)
        finishedTime = self.request.get("finishedTime")
        if finishedTime:
            stat.ActualDistance = float(finishedTime)
        stat.put()

        race = Race.get_by_id(raceID)
        race.Participants.append(stat.key)

        self.response.content_type = 'application/json'
        self.response.out.write(json.dumps({"currentStat" : stat.key.id()}))